﻿#pragma once
// Inner Fire 游戏引擎库
// 索贝尔算子
//
// Copyright (c) 2023 by 尔西大帝. All rights reserved.
//
// 索贝尔算子的工具类。根据《DirectX12游戏开发实战》中的工具类修改。
// 原作者：Frank Luna
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2024-11-26

#include <dx_core/dx_core.h>
#include <vector>

namespace ifire {

class SobelFilter {
public:
  ///< summary>
  /// 因为离屏的纹理需要和屏幕区域一样，所以每次Resize之后都需要重新构建。
  ///</summary>
  SobelFilter(
      ID3D12Device* device, UINT width, UINT height, DXGI_FORMAT format);

  SobelFilter(const SobelFilter& rhs) = delete;
  SobelFilter& operator=(const SobelFilter& rhs) = delete;
  ~SobelFilter() = default;

  CD3DX12_GPU_DESCRIPTOR_HANDLE OutputSrv();

  UINT DescriptorCount() const;

  void BuildDescriptors(CD3DX12_CPU_DESCRIPTOR_HANDLE hCpuDescriptor,
      CD3DX12_GPU_DESCRIPTOR_HANDLE hGpuDescriptor, UINT descriptorSize);

  void OnResize(UINT newWidth, UINT newHeight);

  void Execute(ID3D12GraphicsCommandList* cmdList, ID3D12RootSignature* rootSig,
      ID3D12PipelineState* pso, CD3DX12_GPU_DESCRIPTOR_HANDLE input);

protected:
  void BuildDescriptors();
  void BuildResource();

  ID3D12Device* device_ = nullptr;

  UINT width_ = 0;
  UINT height_ = 0;
  DXGI_FORMAT format_ = DXGI_FORMAT_R8G8B8A8_UNORM;

  Microsoft::WRL::ComPtr<ID3D12Resource> output_ = nullptr;

private:
  CD3DX12_CPU_DESCRIPTOR_HANDLE cpu_srv_handle_;
  CD3DX12_CPU_DESCRIPTOR_HANDLE cpu_uav_handle_;

  CD3DX12_GPU_DESCRIPTOR_HANDLE gpu_srv_handle_;
  CD3DX12_GPU_DESCRIPTOR_HANDLE gpu_uav_handle_;
};

} // namespace ifire
